Memory management refers to operations and processes that are performed to manage the allocation and deallocation of memory for storing objects or other data structures. Typically, most applications use the memory management code that is supplied by the computer language that the applications are written in. However, the memory management code supplied by the computer language may not have certain desirable features such as optimization for performance, optimization for memory allocation, or releasing memory for a set of objects that have a relationship to each other. Therefore, it is advantageous for objects to have their own memory management code.
In the object-oriented world, supplying unique memory management code to an application entails overriding the new and delete operators in every class that is used to create objects in that application. The problem with this is that each class used to create objects in the application require a separate copy of the memory management code to override the new and delete operators in those classes. Having many copies of the memory management code complicates not only routine maintenance but also complicates providing enhancements. For example, whenever a bug is found in the memory management code, the memory management code in each class has to be modified.
When there is a relationship between a set of objects, an application program has to track the relationship between these objects in order to release memory associated with the objects in the proper order. For example, for any given database connection, one or more queries are executed involving statements, and resultsets are returned in response to the queries. Therefore, a hierarchical relationship exists between a database connection, and the related statements, resultsets, and streams. The connection, and related statements, resultsets, and streams can each be represented by their own object and these objects can be organized in a hierarchical tree that reflects the relationship between these objects. For example, the connection object is the top object in a hierarchical tree, the statement objects are directly under the connection object, the resultset objects are directly under the statement objects and so on. Memory is needed for executing methods associated with the objects or for performing computations on behalf of the objects, among other things. Therefore, memory is associated with each object in the hierarchical tree (hereinafter referred to as a “memory management tree”).
A particular object and the objects below that object form a subtree of the hierarchical tree. For example, a particular statement object and all the objects below that particular statement object, such as resultset objects and stream objects, form a subtree of a hierarchical tree. A subtree and the memory associated with the objects in the subtree form a memory management subtree. When a particular object is no longer needed, the memory management subtree, which includes the particular object, the objects below this particular object (hereinafter referred to as “descendents” of the particular object), and the memory associated with all of these objects, is released. For example, once an application program is finished with a statement object, the statement object and all of the statement object's descendants (e.g., resultset objects and stream objects) can be released. The memory associated with these objects is also released. To do this, an application program has to track the relationship between the objects and the associated memory. The release of a memory management subtree needs to be done in such a way that other objects in the hierarchical tree and their associated memory is not released. For example, if a subtree that starts with a particular statement is released, the connection that this particular statement is associated with and the other statements associated with that connection should not be impacted.
Therefore it can be seen that there is a need not only for providing unique memory management code for an application but to provide this memory management code in a way that it is shared by all the objects that are instances of the classes used in the application. Furthermore, it can be seen that there is a need for tracking the relationship between a set of objects in a hierarchical tree and the memory associated with these objects in a way that is transparent to an application program. In so doing, the application program can issue a release for one particular object in the hierarchical tree that results in releasing the memory management subtree that starts with that particular object.